<template>
  <div class="water-level" :style="containerStyle">
    <div class="water-level-title" v-if="title" :style="titleStyle">
      {{ title }}
    </div>
    
    <div class="water-level-container" ref="waterContainer">
      <svg :width="size" :height="size" class="water-level-svg">
        <defs>
          <clipPath :id="`clip-${uid}`">
            <circle :cx="size/2" :cy="size/2" :r="size/2 - strokeWidth" />
          </clipPath>
          
          <linearGradient :id="`gradient-${uid}`" x1="0%" y1="0%" x2="0%" y2="100%">
            <stop offset="0%" :stop-color="gradientColors[0]" />
            <stop offset="100%" :stop-color="gradientColors[1]" />
          </linearGradient>
        </defs>
        
        <!-- 外圆环 -->
        <circle 
          :cx="size/2" 
          :cy="size/2" 
          :r="size/2 - strokeWidth/2"
          fill="none"
          :stroke="borderColor"
          :stroke-width="strokeWidth"
          class="water-border"
        />
        
        <!-- 水波动画 -->
        <g :clip-path="`url(#clip-${uid})`">
          <!-- 背景 -->
          <circle 
            :cx="size/2" 
            :cy="size/2" 
            :r="size/2 - strokeWidth"
            :fill="backgroundColor"
          />
          
          <!-- 水波1 -->
          <path 
            :d="getWavePath(0)" 
            :fill="`url(#gradient-${uid})`"
            class="water-wave wave-1"
            :style="{ transform: `translateY(${waveOffset}px)` }"
          />
          
          <!-- 水波2 -->
          <path 
            :d="getWavePath(Math.PI)" 
            :fill="waveColor"
            :fill-opacity="0.6"
            class="water-wave wave-2"
            :style="{ transform: `translateY(${waveOffset}px)` }"
          />
        </g>
        
        <!-- 百分比文字 -->
        <text 
          :x="size/2" 
          :y="size/2" 
          text-anchor="middle"
          dominant-baseline="middle"
          :style="percentStyle"
          class="water-percent"
        >
          {{ displayPercent }}%
        </text>
      </svg>
    </div>
    
    <div class="water-level-subtitle" v-if="subtitle" :style="subtitleStyle">
      {{ subtitle }}
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'

// Props定义
const props = defineProps({
  value: {
    type: Number,
    default: 0,
    validator: (value) => value >= 0 && value <= 100
  },
  title: {
    type: String,
    default: ''
  },
  subtitle: {
    type: String,
    default: ''
  },
  size: {
    type: Number,
    default: 200
  },
  strokeWidth: {
    type: Number,
    default: 4
  },
  waveHeight: {
    type: Number,
    default: 8
  },
  waveSpeed: {
    type: Number,
    default: 2
  },
  colors: {
    type: Array,
    default: () => ['#00d4ff', '#0099cc']
  },
  borderColor: {
    type: String,
    default: '#00d4ff'
  },
  backgroundColor: {
    type: String,
    default: 'rgba(0, 0, 0, 0.3)'
  },
  textColor: {
    type: String,
    default: '#ffffff'
  },
  animate: {
    type: Boolean,
    default: true
  }
})

// 响应式数据
const uid = ref(Math.random().toString(36).substr(2, 9))
const waterContainer = ref(null)
const currentPercent = ref(0)
const wavePhase = ref(0)
let animationFrame = null

// 计算属性
const containerStyle = computed(() => ({
  textAlign: 'center'
}))

const titleStyle = computed(() => ({
  color: props.textColor,
  fontSize: '16px',
  fontWeight: 'bold',
  marginBottom: '10px'
}))

const subtitleStyle = computed(() => ({
  color: props.textColor,
  fontSize: '12px',
  marginTop: '10px',
  opacity: 0.8
}))

const percentStyle = computed(() => ({
  fontSize: props.size * 0.15 + 'px',
  fontWeight: 'bold',
  fill: props.textColor,
  fontFamily: 'Monaco, Consolas, "Courier New", monospace'
}))

const gradientColors = computed(() => props.colors)

const waveColor = computed(() => props.colors[0])

const displayPercent = computed(() => Math.round(currentPercent.value))

const waveOffset = computed(() => {
  const maxOffset = props.size - props.strokeWidth * 2
  return maxOffset * (1 - currentPercent.value / 100)
})

// 生成波浪路径
const getWavePath = (phase) => {
  const width = props.size
  const height = props.size
  const waveHeight = props.waveHeight
  const waveLength = width / 2
  
  let path = `M 0 ${height}`
  
  for (let x = 0; x <= width; x += 2) {
    const y = height - waveHeight * Math.sin((x / waveLength) * Math.PI * 2 + phase + wavePhase.value)
    path += ` L ${x} ${y}`
  }
  
  path += ` L ${width} ${height} L 0 ${height} Z`
  return path
}

// 更新百分比动画
const updatePercent = (targetPercent) => {
  const startPercent = currentPercent.value
  const diff = targetPercent - startPercent
  const duration = 2000 // 2秒动画
  const startTime = Date.now()
  
  const animate = () => {
    const elapsed = Date.now() - startTime
    const progress = Math.min(elapsed / duration, 1)
    
    // 使用easeOutQuart缓动函数
    const easeProgress = 1 - Math.pow(1 - progress, 4)
    currentPercent.value = startPercent + diff * easeProgress
    
    if (progress < 1) {
      requestAnimationFrame(animate)
    }
  }
  
  animate()
}

// 波浪动画
const animateWaves = () => {
  if (!props.animate) return
  
  const animate = () => {
    wavePhase.value += props.waveSpeed * 0.02
    if (wavePhase.value > Math.PI * 2) {
      wavePhase.value = 0
    }
    
    animationFrame = requestAnimationFrame(animate)
  }
  
  animate()
}

// 停止动画
const stopAnimation = () => {
  if (animationFrame) {
    cancelAnimationFrame(animationFrame)
    animationFrame = null
  }
}

// 监听值变化
watch(() => props.value, (newValue) => {
  updatePercent(newValue)
})

watch(() => props.animate, (newValue) => {
  if (newValue) {
    animateWaves()
  } else {
    stopAnimation()
  }
})

// 生命周期
onMounted(() => {
  currentPercent.value = props.value
  if (props.animate) {
    animateWaves()
  }
})

onUnmounted(() => {
  stopAnimation()
})
</script>

<style scoped>
.water-level {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.water-level-container {
  position: relative;
}

.water-level-svg {
  filter: drop-shadow(0 0 10px rgba(0, 212, 255, 0.3));
}

.water-border {
  stroke-dasharray: 5, 5;
  animation: borderRotate 10s linear infinite;
}

.water-wave {
  transition: transform 0.3s ease;
}

.wave-1 {
  animation: waveFloat1 3s ease-in-out infinite;
}

.wave-2 {
  animation: waveFloat2 4s ease-in-out infinite reverse;
}

.water-percent {
  text-shadow: 0 0 10px rgba(0, 212, 255, 0.5);
  animation: textGlow 2s ease-in-out infinite alternate;
}

@keyframes borderRotate {
  0% {
    stroke-dashoffset: 0;
  }
  100% {
    stroke-dashoffset: 20;
  }
}

@keyframes waveFloat1 {
  0%, 100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(-10px);
  }
}

@keyframes waveFloat2 {
  0%, 100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(10px);
  }
}

@keyframes textGlow {
  0% {
    text-shadow: 0 0 10px rgba(0, 212, 255, 0.5);
  }
  100% {
    text-shadow: 0 0 20px rgba(0, 212, 255, 0.8);
  }
}
</style>
